Auth0経由でGoogleログインしたユーザーでAWS AppSyncへ接続するサンプルアプリをReact Nativeで作ってみた
最近React Nativeを触る機会があったので、簡易的にまとめてブログ化してみました。
ちなみに私はUnbuntu20.04を利用しているため、Androidのみでの作業となりますのでご了承ください。
構成図
Auth0経由でGoogleログインしたユーザーが、AppSync経由でDynamoDBに入っている一覧データを取得します。
事前準備
事前にReact Nativeの環境構築を行う必要があります。
公式ドキュメントを参考に済ませておいてください。
Auth0でApplicationの登録とサンプルアプリの起動
Auth0ダッシュボードの「Applications」から「CREATE APPLICATION」をクリックします。
アプリケーション名とアプリケーションタイプを選択します。
React Nativeのサンプルコードをダウンロードします。
ダウロード画面に遷移すると「Allowed Callback URLs」 「Allowed Logout URLs」の設定をするように表示されます。
設定は「Settings」タブから変更可能です。
ここまでできたら、ダウンロードしたサンプルアプリを起動してみます。
解凍したZipファイル内で、下記のコマンドを実行するとエミュレーターが立ち上がります。
cd 00-login # ライブラリのインストール yarn install # react nativenの起動 yarn start # エミュレータの起動 yarn run android
このまま問題なく起動するかと思いきや、 私の環境では下記のエラーが出ました。
* What went wrong: Execution failed for task ':app:packageDebug'. > A failure occurred while executing com.android.build.gradle.internal.tasks.Workers$ActionFacade > com.android.ide.common.signing.KeytoolException: Failed to read key androiddebugkey from store "/home/seiichi/workspace/react-native-auth0-sample/android/app/debug.keystore": DerInputStream.getLength(): lengthTag=63, too big.
正直ここらへんの設定はまだよく分かっていないのですが、いろいろ調べた結果、
android/app
で鍵を再作成することで対処できました。わかる方いたら教えてください。。。
https://coderwall.com/p/r09hoq/android-generate-release-debug-keystores
keytool -genkey -v -keystore debug.keystore -storepass android -alias androiddebugkey -keypass android -keyalg RSA -keysize 2048 -validity 10000
また、react native 0.62系はバグが多いらしいので、package.json
を書き換えて、0.63系に変更しておきました。
もともと知見がないためココらへんのトラブルシュートでかなり時間をとられましたが、なんとか手元で動かすことができました。
ログイン画面
Googleログイン
アクセストークン取得
AWS AppSyncの作成と設定
こちらを参考にAppSyncの作成を行っていきます。
まず、AWSコンソールでAppSyncのリソースを作成していきます。
モデルの作成
OpenID Connect provider domain (Issuer URL)
にAuth0のテナントのドメインを入力します。
さっそくAppSyncへリクエストを送信したいところですが、Auth0側で少し設定が必要です。
今回はOIDCなので、Auth0側にAPIを登録して、アクセストークンを取得します。
まずは、Auth0ダッシュボードから「CREATE API」をクリックし、APIを作成します。 「Identifier」には、AppSyncのエンドポイントURLを入力してください。
作成したAPIの「Test」タブにアクセストークンが表示されているのでそのまま利用します。
最後にDynamoDBにデータが入っていないので登録しておきます。
AWSコンソールから先ほど取得したアクセストークンを使ってクエリを実行してみます。
React NativeでGoogle認証後にAppSyncへリクエストを送信してみる
こちらを参考にライブラリのインストールやコードの修正をおこなっていきます。
ライブラリのインストール
- aws-mobile-appsync-sdk-js
yarn add aws-appsync aws-appsync-react # React Native 0.60以上は下記も必要 yarn add @react-native-community/netinfo@5.9.4 @react-native-community/async-storage
- apollo
yarn add apollo-client react-apollo@2.5.8
※ React-apollo 3.0
とaws-appsync-react
の間で既知の不具合があるようです。今回はバージョンを下げることで対処しました。
- graphql
yarn add graphql graphql-tag
configファイルの取得
AWSコンソールからaws-exports.js
をダウンロードして、app
配下に設置しておきます。
// WARNING: DO NOT EDIT. This file is automatically generated by AWS Amplify. It will be overwritten. const awsmobile = { "aws_appsync_graphqlEndpoint": "your_graphqlEndpoint", "aws_appsync_region": "ap-northeast-1", "aws_appsync_authenticationType": "OPENID_CONNECT", "aws_appsync_apiKey": "<your_apiKey>", }; export default awsmobile;
コードの修正
app/App.js
を修正
import React, {Component} from 'react'; import {Alert, Text} from 'react-native'; import {graphql, ApolloProvider} from 'react-apollo'; import Auth0 from 'react-native-auth0'; import AWSAppSyncClient, {AUTH_TYPE} from 'aws-appsync'; import {Rehydrated} from 'aws-appsync-react'; import gql from 'graphql-tag'; import appSyncConfig from './aws-exports'; var credentials = require('./auth0-configuration'); const auth0 = new Auth0(credentials); const client = new AWSAppSyncClient({ url: appSyncConfig.aws_appsync_graphqlEndpoint, region: appSyncConfig.aws_appsync_region, auth: { type: AUTH_TYPE.OPENID_CONNECT, jwtToken: async () => { try { const credentials = await auth0.webAuth.authorize({ scope: 'openid profile email', audience: appSyncConfig.aws_appsync_graphqlEndpoint, }); Alert.alert('accessToken: ' + credentials.accessToken); return credentials.accessToken; } catch (error) { Alert.alert(error); } }, }, disableOffline: true, }); const WithProvider = () => ( <ApolloProvider client={client}> <Rehydrated> <App /> </Rehydrated> </ApolloProvider> ); class App extends Component { render() { return <UserComponent />; } } const listUsers = gql` query MyQuery { listMyModelTypes { items { id name } } } `; class User extends Component { render() { return ( <> {this.props.users.map((user, index) => ( <Text key={user.id} style={{fontSize: 40}}> id={user.id}, name={user.name} </Text> ))} </> ); } } const UserComponent = graphql(listUsers, { options: { fetchPolicy: 'network-only', }, props: props => ({ users: props.data.listMyModelTypes ? props.data.listMyModelTypes.items : [], }), })(User); export default WithProvider;
動作確認
コマンドを実行
yarn start yarn run android
エミュレーター
まとめ
簡易的ですが、Auth0経由でGoogleログインしたユーザーがAppSyncにGraphQLのクエリを投げるところまをReact Nativeで実装できました。
本番利用する際には、Google APIsへの正式登録などが必要になってきますので、注意が必要です。
どなたかの役に立てば幸いです。